package controller

import (
	"api_interface/entity"
	"api_interface/service"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

/*
创建提问箱
*/
func Create_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		var box entity.BoxInfo
		if err := c.BindJSON(&box); err != nil {
			// 如果绑定失败，返回400 Bad Request错误
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to get json body",
				"data": nil,
			})
			return
		}
		err := service.CreateBox(&box)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to create box",
				"data": nil,
			})
			return
		}
		var member entity.MemberInfo
		member.Bid = box.Id
		member.Mid = box.Oid
		member.IsOwner = true
		member.IsAdm = false
		err = service.AccountJoinBox(&member)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to create member_info for owner",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

/*
加入提问箱
*/
func Join_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		var member entity.MemberInfo
		if err := c.BindJSON(&member); err != nil {
			// 如果绑定失败，返回400 Bad Request错误
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to get json body",
				"data": nil,
			})
			return
		}
		var check *entity.MemberInfo
		check, err := service.CheckHaveJoin(&member)
		if check != nil || err == nil { //有数据，已经加入过了
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "The user have joined the question_box",
				"data": nil,
			})
			return
		}
		err = service.AccountJoinBox(&member)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to join question_box",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

/*
设置某提问箱成员为管理员
*/
func ChangeAccountAdminRole() gin.HandlerFunc {
	return func(c *gin.Context) {
		var member entity.MemberInfo
		if err := c.BindJSON(&member); err != nil {
			// 如果绑定失败，返回400 Bad Request错误
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to get json body",
				"data": nil,
			})
			return
		}
		err := service.UpdateMemberInfo(&member)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to change user admin role",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

/*
更新提问箱信息
*/
func Updata_question_box_info() gin.HandlerFunc {
	return func(c *gin.Context) {
		var box entity.BoxInfo
		if err := c.BindJSON(&box); err != nil {
			// 如果绑定失败，返回400 Bad Request错误
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to get json body",
				"data": nil,
			})
			return
		}
		err := service.UpdateQuestionBoxInfo(&box)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "error to update question_box_info",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

func Remove_box_member() gin.HandlerFunc {
	return func(c *gin.Context) {
		mid := c.DefaultQuery("mid", "")
		bid := c.DefaultQuery("bid", "")
		err := service.RemoveMemberOfBox(bid, mid)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to remove member",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

/*
根据提问箱id删除提问箱
*/
func Del_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		id := c.DefaultQuery("id", "")

		err := service.DeleteBoxById(id)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to delete box",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

//查询信息中返回类型加入total
/*
获取该用户创建的提问箱(完成)
*/
func Get_user_create_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		mid := c.DefaultQuery("mid", "")
		pag := c.DefaultQuery("page", "")
		page_siz := c.DefaultQuery("page_size", "")
		id, _ := strconv.Atoi(mid)
		page, _ := strconv.Atoi(pag)
		page_size, _ := strconv.Atoi(page_siz)
		//输出json结果给调用方
		boxes, err := service.GetUserCreateBoxByOid(id)
		length := len(*boxes)
		var right int
		right = (page + 1) * (page_size)
		if len(*boxes) < (page+1)*(page_size) { //最后一页没有一页的量
			right = len(*boxes)
		}
		box := (*boxes)[page*page_size : right]
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get the boxes created by user",
				"data": nil,
			})
			return
		}
		type BoxData struct {
			Total int              //`json:"total"`
			Boxes []entity.BoxInfo //`json:"boxes"`
		}
		data := BoxData{
			Total: length,
			Boxes: box,
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": data,
		})
	}
}

/*
通过账户id找到他加入的所有提问箱(完成)
*/
func Desc_member_info(arr *[]entity.MemberInfo) {
	left, right := 0, len(*arr)-1
	for left < right {
		// 交换arr[left]与arr[right]
		(*arr)[left], (*arr)[right] = (*arr)[right], (*arr)[left]
		// 移动指针
		left++
		right--
	}
}
func Get_user_join_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		mid := c.DefaultQuery("mid", "")
		pag := c.DefaultQuery("page", "")
		page_siz := c.DefaultQuery("page_size", "")
		id, _ := strconv.Atoi(mid)
		page, _ := strconv.Atoi(pag)
		page_size, _ := strconv.Atoi(page_siz)
		//输出json结果给调用方
		members, err := service.GetJoinedBoxById(id)
		Desc_member_info(members)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get joined boxes' id",
				"data": nil,
			})
			return
		}
		var boxes []entity.BoxInfo
		for _, mem := range *members {
			box, err := service.GetBoxById(mem.Bid)
			if err != nil {
				c.JSON(http.StatusOK, gin.H{
					"code": 1,
					"msg":  "fail to get the boxes' info",
					"data": nil,
				})
				return
			}
			boxes = append(boxes, *box)
		}
		var right int
		right = (page + 1) * (page_size)
		if len(boxes) < (page+1)*(page_size) {
			right = len(boxes)
		}
		box := boxes[page*page_size : right]
		type BoxData struct {
			Total int              //`json:"total"`
			Boxes []entity.BoxInfo //`json:"boxes"`
		}
		data := BoxData{
			Total: len(boxes),
			Boxes: box,
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": data,
		})
	}
}

/*
通过账户id找到他管理的所有提问箱(完成)//最新的在最前面
*/
func Get_user_manage_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		mid := c.DefaultQuery("mid", "")
		pag := c.DefaultQuery("page", "")
		page_siz := c.DefaultQuery("page_size", "")
		id, _ := strconv.Atoi(mid)
		page, _ := strconv.Atoi(pag)
		page_size, _ := strconv.Atoi(page_siz)
		//输出json结果给调用方
		members, err := service.GetManageBoxById(id)
		Desc_member_info(members)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get joined boxes' id",
				"data": nil,
			})
			return
		}
		var boxes []entity.BoxInfo
		for _, mem := range *members {
			box, err := service.GetBoxById(mem.Bid)
			if err != nil {
				c.JSON(http.StatusOK, gin.H{
					"code": 1,
					"msg":  "fail to get the boxes' info",
					"data": nil,
				})
				return
			}
			boxes = append(boxes, *box)
		}
		type BoxData struct {
			Total int              //`json:"total"`
			Boxes []entity.BoxInfo //`json:"boxes"`
		}
		var right int
		right = (page + 1) * (page_size)
		if len(boxes) < (page+1)*(page_size) {
			right = len(boxes)
		}
		box := boxes[page*page_size : right]
		data := BoxData{
			Total: len(boxes),
			Boxes: box,
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": data,
		})
	}
}

/*
通过账户id找到他管理的所有提问箱(完成)//最新的在最前面
*/
func Find_question_box() gin.HandlerFunc {
	return func(c *gin.Context) {
		title := c.DefaultQuery("title", "")
		pag := c.DefaultQuery("pageNum", "")
		page_siz := c.DefaultQuery("pageSize", "")
		page, _ := strconv.Atoi(pag)
		page_size, _ := strconv.Atoi(page_siz)
		//输出json结果给调用方
		boxes, err := service.SearchManageBoxByTitle(title)
		length := len(*boxes)
		var right int
		right = (page + 1) * (page_size)
		if len(*boxes) < (page+1)*(page_size) { //最后一页没有一页的量
			right = len(*boxes)
		}
		box := (*boxes)[page*page_size : right]
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get the boxes created by user",
				"data": nil,
			})
			return
		}
		type BoxData struct {
			Total int              //`json:"total"`
			Boxdata []entity.BoxInfo //`json:"boxes"`
		}
		data := BoxData{
			Total: length,
			Boxes: box,
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": data,
		})
	}
}

/*
获取提问箱详情信息(完成)
*/
func Get_box_info() gin.HandlerFunc {
	return func(c *gin.Context) {
		bid := c.DefaultQuery("id", "")
		id, _ := strconv.Atoi(bid)
		//输出json结果给调用方
		box, err := service.GetBoxById(id)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get box_info",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": box,
		})
	}
}

/*
获取提问箱的所有者信息(完成)
*/
func GetBoxOwner() gin.HandlerFunc {
	return func(c *gin.Context) {
		bid := c.DefaultQuery("bid", "")
		id, _ := strconv.Atoi(bid)
		//输出json结果给调用方
		mem, err := service.GetBoxOwner(id)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get the owner's id",
				"data": nil,
			})
			return
		}
		owner, err := service.GetAccountById(mem.Mid)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to get the owner's info",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": owner,
		})
	}
}

/*
通过提问箱id找到所有加入的账号(完成)//不需要最新的在最前面
*/
func Get_box_member() gin.HandlerFunc {
	return func(c *gin.Context) {
		bid := c.DefaultQuery("bid", "")
		pag := c.DefaultQuery("page", "")
		page_siz := c.DefaultQuery("page_size", "")
		id, _ := strconv.Atoi(bid)
		page, _ := strconv.Atoi(pag)
		page_size, _ := strconv.Atoi(page_siz)
		members, err := service.GetBoxMemberById(id)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 0,
				"msg":  "fail to get the boxes' member's id",
				"data": nil,
			})
			return
		}
		var accounts []entity.AccountInfo
		for _, mem := range *members {
			mem_account, err := service.GetAccountById(mem.Mid)
			if err != nil {
				c.JSON(http.StatusOK, gin.H{
					"code": 1,
					"msg":  "fail to get the boxes' member's info",
					"data": nil,
				})
				return
			}
			accounts = append(accounts, *mem_account)
		}
		type Data struct {
			Total   int                  //`json:"total"`
			Members []entity.AccountInfo //`json:"boxes"`
		}
		var right int
		right = (page + 1) * (page_size)
		if len(accounts) < (page+1)*(page_size) {
			right = len(accounts)
		}
		account := accounts[page*page_size : right]
		data := Data{
			Total:   len(accounts),
			Members: account,
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": data,
		})
	}
}

/*
查看用户是否已经加入该提问箱
*/
func Check_is_joined() gin.HandlerFunc {
	return func(c *gin.Context) {
		bid_ := c.DefaultQuery("bid", "")
		aid_ := c.DefaultQuery("aid", "")
		bid, _ := strconv.Atoi(bid_)
		aid, _ := strconv.Atoi(aid_)
		member, err := service.Check_is_joined_box(aid, bid)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "fail to check user have joined the box",
				"data": nil,
			})
			return
		}
		if member == nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  "user have not joined the box",
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg":  "success",
			"data": nil,
		})
	}
}

/*
根据提问箱id和查找的页数获取里面的提问
*/
/*不归我管
func Get_que_list() gin.HandlerFunc {
	return func(c *gin.Context) {
		bid := c.DefaultQuery("bid", "")
		pag := c.DefaultQuery("page", "0")
		page, _ := strconv.Atoi(pag)
		page_siz := c.DefaultQuery("page_siz", "10")
		page_size, _ := strconv.Atoi(page_siz)
		//输出json结果给调用方
		ques, err := service.GetQueById(bid, page, page_size)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": http.StatusInternalServerError,
				"msg":  err.Error(),
				"data": nil,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  "success",
			"data": ques,
		})
	}
}
*/
